package cn.com.jdyun.job;
import cn.com.jdyun.mapper.ext.ExtSysConfigMapper;
import cn.com.jdyun.pojo.SysConfig;
import cn.com.jdyun.pojo.UserWallet;
import cn.com.jdyun.service.UserSecService;
import cn.com.jdyun.service.UserWalletService;
import cn.com.jdyun.util.Constant;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * 每天释放0.5个糖果到用户糖果钱包的可用余额中
 *
 * @author Administrator
 */
@Component
public class CandyJob {

    @Autowired
    private UserWalletService userWalletService;
    @Autowired
    private UserSecService userSecService;
    @Autowired
    private ExtSysConfigMapper sysConfigMapper;

    private static final Logger logger = LoggerFactory.getLogger(CandyJob.class);

    // 当前主机cpu个数：用于初始化线程池
    private static final int nThreads = Runtime.getRuntime().availableProcessors();
    // 初始线程池,最大线程数,程池的工作线程空闲后保持存活的时间:0,时间单位：毫秒,用来储存等待执行任务的队列,线程工厂，当队列和线程池都满了时拒绝任务的策略
    private static final ExecutorService pool = new ThreadPoolExecutor(nThreads, nThreads * 2, 0L,
            TimeUnit.MILLISECONDS, new LinkedBlockingDeque<Runnable>(256),
            new ThreadFactoryBuilder().setNameFormat("thread-%d").build(), new ThreadPoolExecutor.AbortPolicy());
    private static final Set<String> keys = new HashSet<String>();

    @Scheduled(cron = "0 40 23 * * ?") //每天凌晨执行
    //@Scheduled(cron = "0 0/5 * * * ?") //每五分钟执行一次
    public void timerToNow() throws Exception {
        // 获取所有用戶
        List<UserWallet> wallets = userWalletService.findLockedCoinWallet(Constant.CANDY);
        if (wallets == null || wallets.size() == 0) {
            return;
        }
        int i = 0;
        while (wallets.size() > i) {
            try {
                doActions(wallets.get(i));
            } catch (Exception e) {
                logger.error(e.getMessage());
            } finally {
                i++;
                if (i % 10 == 9) {
                    //每十个处理，停顿1s
                    Thread.sleep(1000);
                }
            }
        }
    }

    private void doActions(final UserWallet wallet) throws InterruptedException {
        //如果队列线程数超过200，则有可能超出线最大队列数限制
        /*while (keys.size() >= 200) {
            Thread.sleep(1000);
        }
        keys.add(wallet.getUserId());
        pool.execute(() -> {
            
        });*/
    	try {
//        	Boolean result = userSecService.isAuthentication(wallet.getUserId());
//            //判断用户是否完成实名认证
//            if (result == null || !result) {
//                return;
//            }
            SysConfig dayFreeCandyConfig = sysConfigMapper.selectByCode(Constant.DAY_FREE_CANDY);
            userWalletService.freeCandyCoin(wallet, dayFreeCandyConfig.getInitValue(),Constant.COINTYPE_SSSP);

        } catch (Exception e) {
            logger.error(e.getMessage());
        } finally {
            keys.remove(wallet.getUserId());
        }
    }
}
